package com.shareyi.jshop.autocode.tableutil;
import com.shareyi.joywindow.sys.utils.AutoCodeFileUtil
import com.shareyi.jshop.autocode.domain.AutoCodeParams;
import com.shareyi.jshop.autocode.domain.AutoMake
import com.shareyi.jshop.autocode.domain.TableModel
import com.shareyi.jshop.autocode.domain.Template
import com.shareyi.jshop.autocode.utils.AutoCodeConstant
import com.shareyi.fileutil.FileUtil
import org.apache.commons.collections.MapUtils;


public class AutoCodeUtil {
	
	
	/**
	 * 根据tableModel文件自动生成代码
	 * @param filePath tableModel文件路径
	 * @param config 
	 * @return 
	 */
	static String  generateCodeByTableModelFile(AutoCodeParams autoMakeParams) {
		
		StringBuilder message=new StringBuilder();
		//通过自动代码配置文件 和 模板文件目录生成java对象
		AutoMake autoMake=AutoCodeUtil.getAutoMake(autoMakeParams.autoXmlPath,autoMakeParams.templateBaseDir);
		if(autoMakeParams.baseDir!=null){
			autoMake.baseDir=autoMakeParams.baseDir;
		}

		/*******获取配置文件相关值 start********/
        //获取公共字典项map
		def dictFilePath=autoMake.getProp(AutoCodeConstant.DICT_PATH);
		def dictMap=XmlUtils.getDictMap(dictFilePath);
		
		//获取片段代码路径
		def snippetTemplatePath=autoMake.getProp(AutoCodeConstant.SNIPPET_TEMPLATE_PATH);
		def snippetTemplateMap=XmlUtils.getSnippetTemplateMap(snippetTemplatePath);

		//获取片段text路径
		def extendTextConfPath=autoMake.getProp(AutoCodeConstant.EXTEND_TEXT_CONFIG_PATH);
		def extendConfigMap=XmlUtils.readKeyMapFile(extendTextConfPath);

		//获取数据库到Java类型映射
		def db2javaTypeMapPath=autoMake.getProp(AutoCodeConstant.DBTYPE_JAVA_MAP_PATH);
		def db2javaTypeMap=XmlUtils.readKeyMapFile(db2javaTypeMapPath);

		//获取数据库到页面类型映射（列表类型为前台类型）
		def dbType2ColumnTagMapPath=autoMake.getProp(AutoCodeConstant.DBTYPE_COLUMNTAG_MAP_PATH);
		def dbType2ColumnTagMap=XmlUtils.readKeyMapFile(dbType2ColumnTagMapPath);


		//获取requireJs文件map
		def requireJsMapPath=autoMake.getProp(AutoCodeConstant.REQUIRE_JS_MAP_PATH);
		def requireConfigMap=XmlUtils.readRequireConfigFile(requireJsMapPath);

		RequireUtil requireUtil=new RequireUtil();
		requireUtil.setRequireConfigMap(requireConfigMap)

		/*******获取配置文件相关值 end********/


		//如果autoMake不为空，执行处理
		if(autoMake!=null) {
			TableModel tableModel=XmlUtils.getTableModelByFile(autoMakeParams.tableModelPath);
			if(tableModel.dictMap!=null){
				dictMap.putAll(tableModel.dictMap);
			}

			/** 如果配置文件不为空，则采用配置文件的数据来使用*/
			TableNameUtil tableNameUtil=new TableNameUtil();
			if(MapUtils.isNotEmpty(db2javaTypeMap)){
				tableNameUtil.dataTypeMap=db2javaTypeMap;
			}
			if(MapUtils.isNotEmpty(dbType2ColumnTagMap)){
				tableNameUtil.jspTagMap=dbType2ColumnTagMap;
			}


			//构造片段代码需要的MAP，片段代码直接从本map中获取数据
			def templateBinding=["tableModel":tableModel,"tableDefine":tableModel.tableDefine,
								 "tableNameUtil":tableNameUtil,"PubUtils":PubUtils,"requireUtil":requireUtil,
								"config":autoMakeParams.config,"extendConf":extendConfigMap,
								"dictMap":dictMap,"snippetTemplateMap":snippetTemplateMap];
		
			SnippetTemplateUtil snippetTemplateUtil=new SnippetTemplateUtil();
			snippetTemplateUtil.binding=templateBinding;
			snippetTemplateUtil.dictMap=dictMap;
			snippetTemplateUtil.snippetTemplateMap=snippetTemplateMap;

			//构造模板需要的MAP，模板直接从本map中获取数据
			def binding=["tableModel":tableModel,"tableDefine":tableModel.tableDefine,
						 "tableNameUtil":tableNameUtil,"PubUtils":PubUtils,"requireUtil":requireUtil,
						"config": autoMakeParams.config,"extendConf":extendConfigMap,
						 "snippetTemplateUtil":snippetTemplateUtil,"dictMap":dictMap,"dictUtil":snippetTemplateUtil];




			TemplateUtil templateUtil=new TemplateUtil();
			//获取模板列表对象，对每个模板生成模板结果
			List<Template> templates=autoMake.getTemplates();
			for (Template template : templates) {
				try{
                    //如果页面上没有选择本template，自动跳过
                    if(!autoMakeParams.containsTemplateIds(template.id)){
                        message.append "未选择本模板，略过:["+template.desc+"],templateId="+template.id+"\n";
                        continue;
                    }

                    String destFile= template.destFile;
                    String renderPath=templateUtil.renderContent(destFile, binding);
                    renderPath=renderPath.replaceAll("//", "/");
                    String content=templateUtil.renderTemplate(template,binding);
					if(content==null){
						message.append "模板不存在和为空，略过:["+template.desc+"],templateId="+template.id+"\n";
						continue;
					}

                    File file=new File(autoMake.getBaseDir(),renderPath);
                    if(file.exists()){
                        //如果不允许覆盖，直接略过
                        if(!autoMakeParams.overideFlag){
                            message.append "文件已存在，不允许覆盖，略过:"+file.absolutePath+"\n";
                            continue;
                        }

                    }

                    File f=FileUtil.makeSureFileExsit( new File(autoMake.getBaseDir(),renderPath));
                    if(f!=null){
                        f.withWriter("UTF-8"){writer-> writer.write content}
                    }

                    message.append "["+template.desc+"]模板执行成功，生成文件在："+f.absolutePath+"\n";
				}catch(Exception e){
				e.printStackTrace();
				message.append "["+template.desc+"]模板执行失败，原因是："+e.message+"\n";
				}
			}
			message.append tableModel.tableDefine.dbTableName+"表的代码自动生成成功！\n";
			
			return message.toString();
		}
	}

    /**
     * 获取autoMake对象
     * @param autoXmlPath
     * @param templateBaseDir
     * @return
     */
    public static AutoMake getAutoMake(String autoXmlPath,   String templateBaseDir){
        autoXmlPath=AutoCodeFileUtil.parseFilePath(autoXmlPath);
        templateBaseDir=AutoCodeFileUtil.parseFilePath(templateBaseDir);
        AutoMake autoMake=XmlUtils.getAutoMake(autoXmlPath,templateBaseDir);
        return autoMake;
    }
	
}
